package com.skyline.energy.mongo.impl;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.regex.Pattern;

import net.sf.cglib.core.ReflectUtils;

import org.bson.types.BSONTimestamp;
import org.bson.types.Code;
import org.bson.types.ObjectId;

import com.mongodb.DBObject;
import com.skyline.common.reflection.MethodUtils;
import com.skyline.energy.exception.DaoGenerateException;
import com.skyline.energy.mongo.BeanMapper;
import com.skyline.energy.utils.BeanAutoDetect;

/**
 * 支持自动类型映射的BeanMapper
 * 
 * 
 * @author wuqh
 * 
 * @param <T>
 */
public class AutoDetectBeanMapper<T> extends BeanAutoDetect implements BeanMapper<T> {
	public AutoDetectBeanMapper(Class<T> clazz) throws DaoGenerateException {
		super(clazz);
	}

	@SuppressWarnings("unchecked")
	@Override
	public T mapper(DBObject o) {
		T result = (T) ReflectUtils.newInstance(clazz);

		if (result == null) {
			return result;
		}

		Map<String, Object> resultMap = o.toMap();

		for (Entry<String, Object> entry : resultMap.entrySet()) {
			String key = entry.getKey();
			Object val = entry.getValue();
			Method writeMethod = writeMethods.get(key);
			MethodUtils.invokeMethod(result, writeMethod, convert(val, key));
		}

		return result;
	}

	@Override
	public boolean isAllowAutoMapType(Class<?> clazz) {
		boolean isBsonClass = isBsonType(clazz);
		return isSimpleType(clazz) || isAllowNumber(clazz) || clazz.equals(UUID.class) || clazz.equals(Pattern.class)
				|| isBsonClass;
	}

	private boolean isBsonType(Class<?> clazz) {
		return clazz.equals(Code.class) || clazz.equals(BSONTimestamp.class) || clazz.equals(ObjectId.class);
	}

}
